﻿
#include "SwfDataVo.h"
#include "../utils/Utils.h"
#include "../DevInclude.h"



void CSwfBitContainer::setContainerPos(CCSprite* container,const CCPoint&  base){
    
    CCSize oSize=container->getContentSize();
    float curContainerW=oSize.width ;
    float curContainerH=oSize.height;
     
 
    container->setPositionX(-base.x+curContainerW/2.0f );
    container->setPositionY(base.y-curContainerH/2.0f );
    
}


void CSwfBitContainer::initWithFile(const char* path){
    if(gSprite.size()==0){
        CCSprite* sprite=CCSprite::create();
        addChild(sprite);
        gSprite.push_back(sprite);
    }
    
    for(int i=0;i<gSprite.size();i++){
        if(i==0){
            gSprite[i]->initWithFile(path);
        }else{ 
            gSprite[i]->setVisible(false);
        }
    }
}

void CSwfBitContainer::setSwfBitVo(CSwfBitVo* vo){
    if(!vo){
        return;
    }
    for(int i=gSprite.size();i<vo->gBaseDataConf.size();i++){ 
        CCSprite* sprite=CCSprite::create();
        addChild(sprite);
        gSprite.push_back(sprite);
    }
    
    int minx=10000, miny=10000,maxx=-10000,maxy=-10000;
    
    for(int i=0;i<gSprite.size();i++){
        if (i<vo->gBaseDataConf.size()) {
            CCSpriteFrame* frame=vo->gSpriteFrame[i]; 
            gSprite[i]->setDisplayFrame(frame);
            CCPoint base=CCPointZero;
                
            if(vo->gBaseDataConf[i]->cName.size()>0){
                base.x=vo->gBaseDataConf[i]->nBaseX ;
                base.y=vo->gBaseDataConf[i]->nBaseY ;
            }
            setContainerPos(gSprite[i] ,base);  
            
            
            if(gSprite[i]->getPositionX()< minx){
                minx=gSprite[i]->getPositionX();
            }
            
            if(gSprite[i]->getPositionX()+gSprite[i]->getContentSize().width> maxx){
                maxx=gSprite[i]->getPositionX()+gSprite[i]->getContentSize().width;
            }
            
            
            if(gSprite[i]->getPositionY()< miny){
                miny=gSprite[i]->getPositionY();
            }
            
            if(gSprite[i]->getPositionY()+gSprite[i]->getContentSize().height> maxy){
                maxy=gSprite[i]->getPositionY()+gSprite[i]->getContentSize().height;
            }
            
            gSprite[i]->setVisible(true);
            gSprite[i]->displayFrame()->getTexture()->setAliasTexParameters();
            
        }else{
            gSprite[i]->setVisible(false);
        }
    }
    
   
    if(maxx>minx && maxy>miny){
        setContentSize(CCSizeMake(maxx-minx, maxy-miny));
    }
     
}


void CSwfBitContainer::setOpacity(GLubyte opacity){
    
    for(int i=0;i<gSprite.size();i++){ 
        gSprite[i]->setOpacity(opacity);
    }
}


CSwfBitVo::~CSwfBitVo(){
    
    
}

void CSwfDataVo::setUrl(const string& url ,bool force){
    
    if(url==oUrl   ){
        return ;
    }
    oUrl=url;
    
    if(cUrl!=""){
        clearCache();
    }
    
    cUrl=url; 
    if(url!=""){
        
        size_t startPos = cUrl.find_last_of(".");
        cUrl.erase(startPos);
        
        cFileName=cUrl;
        
        size_t endPos=cFileName.find_last_of("/");
        
        if(cFileName.npos!=endPos){
            cFileName.erase(0, endPos+1);
            
        }
        plists.clear();
        baseDatas.clear();
        
        unsigned long size;
		string cBaseConf=cUrl+".dat";
		string temp=CCFileUtils::sharedFileUtils()->fullPathForFilename(parseFilePath(cBaseConf.c_str()).c_str());
        cBaseConf=temp.c_str();
        unsigned char * pBytes = CCFileUtils::sharedFileUtils()->getFileData(cBaseConf.c_str(), "rb", &size);
        
        if(size>0){ 
            ByteBuffer reader;
            reader.append( pBytes,size);
            int totalCount; 
            reader>>plistCount;
            if(plistCount>=100){
                reader>>totalCount;
                plistCount-=100;
                for(int i=0;i<totalCount;i++){
                    int action, dir,frame, posX,posY,part;
                    reader>>action;
                    reader>>dir;
                    reader>>frame;
                    reader>>posX;
                    reader>>posY;
                    reader>>part;
                    
                    CCPoint pos(posX/10.0f,posY/10.0f);
                    baseDatas.insert(pair<int, CCPoint>((part+1)*10000+action*1000+dir*100+frame, pos));
                    //baseDatas[action*1000+dir*100+frame]=pos;
                }
                is9Part=true;
            }else{
                reader>>totalCount;
                
                for(int i=0;i<totalCount;i++){
                    int action, dir,frame, posX,posY;
                    reader>>action;
                    reader>>dir;
                    reader>>frame;
                    reader>>posX;
                    reader>>posY;
                    
                    CCPoint pos(posX,posY);
                    baseDatas.insert(pair<int, CCPoint>(action*1000+dir*100+frame, pos));
                    //baseDatas[action*1000+dir*100+frame]=pos;
                }
                is9Part=false;
            }
           
         
        }
        CC_SAFE_DELETE_ARRAY(pBytes);
        
        if(force){
            for(int i=0;i<plistCount;i++){ 
                string path =cUrl+"_"+parseString(i)+".plist";
                path=parseFilePath(path.c_str());
                
                CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile( path.c_str());
                LoadingPro::shareLoadingPro()->addCachePlist(path);
            }
        }
         
    }
}

void CSwfDataVo::clearCache(){ 
    //优化完不需要处理
    for(int i=0;i<plistCount;i++){
        string path =cUrl+"_"+parseString(i)+".plist";
        path=parseFilePath(path.c_str());  
        LoadingPro::shareLoadingPro()->removeHasLoadPlist(path.c_str());
    } 
}
 

CSwfDataVo::CSwfDataVo(){ 
    plistCount=0;
    is9Part=false;
}

CSwfDataVo::~CSwfDataVo(){
    for(int i=0;i<gBaseDataConf.size();i++){
        SAFE_DEL(gBaseDataConf[i]);
    }
    gBaseDataConf.clear();
}





int getActionId(string name){
    
    if(name=="stand"){
        return 1;
    }
    
    if(name=="run"){
        return 2;
    }
    
    if(name=="attack"){
        return 3;
    }
    
    if(name=="skyStand"){
        return 4;
    }
    
    if(name=="skyRun"){
        return 5;
    }
    
    if(name=="skyAttack"){
        return 6;
    }
    if(name=="jump"){
        return 7;
    }
    
    return 0;
}
/**
 * 获取某帧的图片
 * @param frameName 帧标签名
 * @param index 从0开始的帧索引
 * @param dir 方向 上1，右上2，依次到8
 * @return BitmapData与x,y
 */
CSwfBitVo* CSwfDataVo::getBitAndPos(const char* frameName, int index, int  dir ){
    
    if(is9Part){
        return getBitAndPos9(frameName, index,dir);
    }
    if(cUrl==""){
        return NULL;
    }
    if (dir > 5)
    { 
        dir = 10 - dir; // 镜像
    }
    curKey = (cFileName)+"_"+string(frameName) +"_"+ parseString(dir)+"_"+parseString(index+1)+".png";
     
    CCSpriteFrame* pFrame=   CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(curKey.c_str());
    
    if(pFrame){
        CSwfBitVo* ret=new CSwfBitVo();
        if(gBaseDataConf.size()==0){
            SwfPosData* newConf=new SwfPosData();
            gBaseDataConf.push_back(newConf);
        }
            
           
        gBaseDataConf[0]->cName="dat";
        int actionId=getActionId(frameName);
        CCPoint pos= baseDatas[actionId*1000+dir*100+index];
        gBaseDataConf[0]->nBaseX=pos.x;
        gBaseDataConf[0]->nBaseY=pos.y;
            
            
        ret->gBaseDataConf.push_back(gBaseDataConf[0]);
        ret->gSpriteFrame.push_back(pFrame);
       
        ret->autorelease();
        return ret;
    }else{
        for(int i=0;i<plistCount;i++){
            string path =cUrl+"_"+parseString(i)+".plist";
            path=parseFilePath(path.c_str());
            
            LoadingPro::shareLoadingPro()->addTryPlist(path);
            
        }
    }
    
    return NULL;
    
}


CSwfBitVo* CSwfDataVo::getBitAndPos9(const char* frameName, int index, int  dir ){
    
    if(cUrl==""){
        return NULL;
    }
    if (dir > 5)
    {
        dir = 10 - dir; // 镜像
    }
    
    
    
    
    map<int,CCSpriteFrame* >gSpriteFrames;
    
     
    
    for(int i=1 ; i<=9;i++){
        int actionId=getActionId(frameName);
        int partNum=i*10000+actionId*1000+dir*100+index;
        if(baseDatas.find(partNum)!=baseDatas.end()){
            
            curKey = (cFileName)+"_"+string(frameName) +"_"+ parseString(dir)+"_"+parseString(index+1)+"_part_"+parseString(i)+".png";
            
            CCSpriteFrame* pFrame=   CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(curKey.c_str());
            if(pFrame){
                pFrame->getTexture()->setAliasTexParameters();
                gSpriteFrames[i]=pFrame;
            }
        }
    }
    
     if(!gSpriteFrames.empty()){
        CSwfBitVo* ret=new CSwfBitVo();
        
        if(is9Part){
            
            for(int i=gBaseDataConf.size(); i<9;i++){
                SwfPosData* newConf=new SwfPosData();
                gBaseDataConf.push_back(newConf);
            }
            
            map<int,CCSpriteFrame* >::iterator it= gSpriteFrames.begin();
             
            for( int i=0; it!=gSpriteFrames.end();it++,i++){
                int actionId=getActionId(frameName);
                int partNum=(it->first)*10000+actionId*1000+dir*100+index;
                
                
                gBaseDataConf[i]->cName="dat";
                CCPoint pos= baseDatas[partNum];
                gBaseDataConf[i]->nBaseX=pos.x;
                gBaseDataConf[i]->nBaseY=pos.y;
                
                
                ret->gBaseDataConf.push_back(gBaseDataConf[i]);
                ret->gSpriteFrame.push_back(it->second);
               
                
            }
        }
        
        ret->autorelease();
        return ret;
         
    }else{
        for(int i=0;i<plistCount;i++){
            string path =cUrl+"_"+parseString(i)+".plist";
            path=parseFilePath(path.c_str());
            
            LoadingPro::shareLoadingPro()->addTryPlist(path);
            
        }
    }
    
    return NULL;
}



